package site.isscloud.jt809;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class JT809Message {
    private byte[] msgHead;     // 4字节
    private int msgId;          // 2字节
    private int msgLen;         // 4字节
    private int msgSn;          // 4字节
    private int gnssCenterId;   // 4字节
    private byte[] version;     // 3字节
    private byte encryptFlag;   // 1字节
    private int encryptKey;     // 4字节
    private byte[] msgBody;     // 变长
    private short crcCode;      // 2字节
    
    // 构造请求消息
    public JT809Message(int msgId, int msgSn, int gnssCenterId, byte[] msgBody) {
        this.msgHead = JT809Utils.MSG_HEAD;
        this.msgId = msgId;
        this.msgLen = (msgBody != null) ? msgBody.length : 0;
        this.msgSn = msgSn;
        this.gnssCenterId = gnssCenterId;
        this.version = new byte[]{0x01, 0x00, 0x00}; // V1.0.0
        this.encryptFlag = 0x00; // 不加密
        this.encryptKey = 0;
        this.msgBody = msgBody;
        this.crcCode = calculateCrc();
    }
    
    // 从字节数组解析消息
    public JT809Message(byte[] data) {
        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);
        
        // 读取消息头
        this.msgHead = new byte[4];
        buffer.get(msgHead);
        
        // 读取其他字段
        this.msgId = JT809Utils.readUnsignedShort(buffer);
        this.msgLen = (int) JT809Utils.readUnsignedInt(buffer);
        this.msgSn = (int) JT809Utils.readUnsignedInt(buffer);
        this.gnssCenterId = buffer.getInt();
        
        this.version = new byte[3];
        buffer.get(version);
        
        this.encryptFlag = buffer.get();
        this.encryptKey = buffer.getInt();
        
        // 读取消息体
        this.msgBody = new byte[msgLen];
        buffer.get(msgBody);
        
        // 读取CRC
        this.crcCode = buffer.getShort();
    }
    
    // 计算CRC校验码
    private short calculateCrc() {
        ByteBuffer buffer = ByteBuffer.allocate(4 + 2 + 4 + 4 + 4 + 3 + 1 + 4 + msgLen)
                .order(ByteOrder.BIG_ENDIAN);
        
        buffer.put(msgHead);
        buffer.putShort((short) msgId);
        buffer.putInt(msgLen);
        buffer.putInt(msgSn);
        buffer.putInt(gnssCenterId);
        buffer.put(version);
        buffer.put(encryptFlag);
        buffer.putInt(encryptKey);
        if (msgBody != null) {
            buffer.put(msgBody);
        }
        
        return JT809Utils.calculateCRC16(buffer.array());
    }
    
    // 验证CRC
    public boolean verifyCrc() {
        return calculateCrc() == crcCode;
    }
    
    // 转换为字节数组
    public byte[] toByteArray() {
        ByteBuffer buffer = ByteBuffer.allocate(4 + 2 + 4 + 4 + 4 + 3 + 1 + 4 + msgLen + 2)
                .order(ByteOrder.BIG_ENDIAN);
        
        buffer.put(msgHead);
        buffer.putShort((short) msgId);
        buffer.putInt(msgLen);
        buffer.putInt(msgSn);
        buffer.putInt(gnssCenterId);
        buffer.put(version);
        buffer.put(encryptFlag);
        buffer.putInt(encryptKey);
        if (msgBody != null) {
            buffer.put(msgBody);
        }
        buffer.putShort(crcCode);
        
        return buffer.array();
    }
    
    // Getters
    public int getMsgId() { return msgId; }
    public int getMsgSn() { return msgSn; }
    public byte[] getMsgBody() { return msgBody; }
    public int getGnssCenterId() { return gnssCenterId; }
    public byte[] getMsgHead() { return msgHead; }
    public int getMsgLen() { return msgLen; }
    public byte[] getVersion() { return version; }
    public byte getEncryptFlag() { return encryptFlag; }
    public int getEncryptKey() { return encryptKey; }
    public short getCrcCode() { return crcCode; }
    
    @Override
    public String toString() {
        return String.format("JT809Message{msgHead=%s, msgId=0x%04X, msgLen=%d, msgSn=%d, gnssCenterId=%d, version=%s, encryptFlag=0x%02X, encryptKey=%d, crcCode=0x%04X}", 
                JT809Utils.bytesToHex(msgHead), msgId, msgLen, msgSn, gnssCenterId, JT809Utils.bytesToHex(version), encryptFlag, encryptKey, crcCode);
    }
}
